using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Text.RegularExpressions;

namespace SalienceEngineDemo
{
    public class HighlightManager
    {
        private class displaySettings
        {
            public displaySettings(String backColor)
            {
                m_backColor = backColor;
                m_foreColor = null;
            }

            public displaySettings(String backColor, String foreColor)
            {
                m_backColor = backColor;
                m_foreColor = foreColor;
            }

            public void Combine(displaySettings otherSetting)
            {
                MatchedField = otherSetting;
            }

            public displaySettings MatchedField = null;
            public String MatchedFieldName;
            public String m_backColor;
            public String m_foreColor;

        }
        //every entity type to display, and its color.
        private Dictionary<String, displaySettings> highlightColors = new Dictionary<string, displaySettings>();
        private Dictionary<String, displaySettings> hiddenColors = new Dictionary<string, displaySettings>();

        //alternative ways of expressing an highlight type.
        private Dictionary<String, String> synonyms = new Dictionary<string, string>();

        //entity types we want to hide. Don't put them in highlightColors!
        private List<String> hiddenTypes = new List<string>();

        public void AddHighlight(String type, String backColor)
        {
            highlightColors.Add(type, new displaySettings(backColor));
        }

        public void AddHighlight(String type, String backColor, String foreColor)
        {
            highlightColors.Add(type, new displaySettings(backColor, foreColor));
        }

        public void AddHighlightPair(String Type, String backColor, String Type2, String backColor2)
        {
            displaySettings mainSetting = new displaySettings(backColor);
            displaySettings secondSetting = new displaySettings(backColor2);
            mainSetting.MatchedField = secondSetting;
            mainSetting.MatchedFieldName = Type2;
            highlightColors.Add(Type, mainSetting);
            hiddenColors.Add(Type2, secondSetting);
        }

        public void AddSynonym(String otherName, String displayname)
        {
            synonyms.Add(otherName, displayname);
        }

        public void HideEntry(String toHide)
        {
            hiddenTypes.Add(toHide);
            if(highlightColors.ContainsKey(toHide))
            {
                highlightColors.Remove(toHide);
            }
        }

        public void CreateLegend(FlowLayoutPanel legendPanel)
        {
            Label entityLabel = new Label();
            //equally divide the available space between each key in the legend.
            int width = (legendPanel.Size.Width - legendPanel.Padding.Horizontal - (highlightColors.Count * entityLabel.Margin.Horizontal)) / highlightColors.Count;
            //use the available vertical space.
            int height = legendPanel.Size.Height - legendPanel.Padding.Vertical;
            foreach (KeyValuePair<String, displaySettings> entity_color in highlightColors)
            {
                if (entity_color.Value.MatchedField != null)
                {
                    entityLabel = new TwoToneLabel(ColorTranslator.FromHtml(entity_color.Value.MatchedField.m_backColor));
                    entityLabel.Text = entity_color.Key.Replace('_', ' ') + "\n" + entity_color.Value.MatchedFieldName.Replace('_', ' ');
                }
                else
                {
                    entityLabel = new Label();
                    entityLabel.Text = entity_color.Key.Replace('_', ' ');
                }
                entityLabel.BackColor = ColorTranslator.FromHtml(entity_color.Value.m_backColor);
                if (entity_color.Value.m_foreColor != null)
                {
                    entityLabel.ForeColor = ColorTranslator.FromHtml(entity_color.Value.m_foreColor);
                }
                
                entityLabel.BorderStyle = BorderStyle.FixedSingle;
                entityLabel.Size = new Size(width, height);
                entityLabel.TextAlign = ContentAlignment.MiddleCenter;
                legendPanel.Controls.Add(entityLabel);
            }
        }

        public string FormatResults(string sText)
        {
            string sRet = "<html><head><style>";
            //specify the coloring for each entity type.
            foreach (KeyValuePair<String, displaySettings> item_color in highlightColors)
            {
                sRet += ".lxa_" + item_color.Key + " {background-color: " + item_color.Value.m_backColor;
                if (item_color.Value.m_foreColor != null)
                {
                    sRet += "; color: " + item_color.Value.m_foreColor + "}\n";
                }
                else
                {
                    sRet += "}\n";
                }
            }
            foreach (KeyValuePair<String, displaySettings> item_color in hiddenColors)
            {
                sRet += ".lxa_" + item_color.Key + " {background-color: " + item_color.Value.m_backColor;
                if (item_color.Value.m_foreColor != null)
                {
                    sRet += "; color: " + item_color.Value.m_foreColor + "}\n";
                }
                else
                {
                    sRet += "}\n";
                }
            }
            sRet += "body { font-family: Trebuchet MS; font-size: "+Properties.Settings.Default.fFontSize.ToString()+"pt; color:#000000; background-color:#FFFFFF}\n";

            sRet += "</style></head><body>";

            string sTemp = sText;
            //replace all entity type tags with a reference to the font class with the same name.
            foreach (KeyValuePair<String, displaySettings> item_color in highlightColors)
            {
                sTemp = Regex.Replace(sTemp,@"\[LXA_"+item_color.Key+@"[^\]]*\]","<font class=\"lxa_" + item_color.Key + "\">");
                sTemp = Regex.Replace(sTemp, @"\[/LXA_" + item_color.Key + @"[^\]]*\]", "</font>");
            }
            foreach (KeyValuePair<String, displaySettings> item_color in hiddenColors)
            {
                sTemp = Regex.Replace(sTemp, @"\[LXA_" + item_color.Key + @"[^\]]*\]", "<font class=\"lxa_" + item_color.Key + "\">");
                sTemp = Regex.Replace(sTemp, @"\[/LXA_" + item_color.Key + @"[^\]]*\]", "</font>");
            }
            foreach (KeyValuePair<String, String> others in synonyms)
            {
                sTemp = Regex.Replace(sTemp, @"\[LXA_" + others.Key + @"[^\]]*\]", "<font title=\""+others.Key+"\" class=\"lxa_" + others.Value + "\">");
                sTemp = Regex.Replace(sTemp, @"\[/LXA_" + others.Key + @"[^\]]*\]", "</font>");
            }
            //hidden types just have their tags stripped away.
            foreach (String hidden in hiddenTypes)
            {
                sTemp = Regex.Replace(sTemp, @"\[LXA_" + hidden + @"[^\]]*\]", "");
                sTemp = Regex.Replace(sTemp, @"\[/LXA_" + hidden + @"[^\]]*\]", "");

            }

            sRet += sTemp;

            sRet += "</body></html>";

            return sRet;
        }
    }
}
